package me.chanjar.weixin.mp.bean.card;

import java.io.Serializable;
import java.util.Date;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import me.chanjar.weixin.common.util.DateDeserializer;
import me.chanjar.weixin.common.util.DateSerializer;

/**
 * 基本的卡券数据，所有卡券类型通用
 * 
 * @author Debenson
 * @since 0.1
 */
public class BaseInfo implements Serializable {
  private static final long serialVersionUID = -487394618551492765L;

  /**
   * 卡券ID，创建的时候无，读取的时候有
   */
  private String id;

  /**
   * 状态 CARD_STATUS_NOT_VERIFY”,待审核； “CARD_STATUS_VERIFY_FALL”,审核失败；
   * “CARD_STATUS_VERIFY_OK”，通过审核； “CARD_STATUS_USER_DELETE”，卡券被用户删除；
   * “CARD_STATUS_USER_DISPATCH”，在公众平台投放过的卡券
   */
  private CardStatus status;

  /**
   * 卡券的商户logo，建议像素为300*300
   */
  @JsonProperty("logo_url")
  private String logoUrl;

  /**
   * Code展示类型
   */
  @JsonProperty("code_type")
  private CodeType codeType;

  /**
   * 商户名字,字数上限为12个汉字
   */
  @JsonProperty("brand_name")
  private String brandName;

  /**
   * 卡券名，字数上限为9个汉字。(建议涵盖卡券属性、服务及金额)
   */
  private String title;

  /**
   * 券颜色。按色彩规范标注填写Color010-Color100
   */
  private String color;

  /**
   * 卡券使用提醒，字数上限为16个汉字
   */
  private String notice;

  /**
   * 卡券使用说明，字数上限为1024个汉字
   */
  private String description;

  /**
   * 商品信息
   */
  private Sku sku;

  /**
   * 时间信息
   */
  @JsonProperty("date_info")
  private DateInfo dateInfo;

  /**
   * 是否自定义Code码。填写true或false，默认为false。通常自有优惠码系统的开发者选择自定义Code码，在卡券投放时带入
   */
  @JsonProperty("use_custom_code")
  private Boolean useCustomCode;

  /**
   * 表示该卡券为预存code模式卡券， 须导入超过库存数目的自定义code后方可投放， 填入该字段后，quantity字段须为0,须导入code
   * 后再增加库存
   */
  @JsonProperty("get_custom_code_mode")
  private GetCustomCodeMode getCustomCodeMode;

  /**
   * 是否指定用户领取，填写true或false。默认为false
   */
  @JsonProperty("bind_openid")
  private Boolean bindOpenId;

  /**
   * 客服电话
   */
  @JsonProperty("service_phone")
  private String servicePhone;

  /**
   * 机场位置ID, 调用POI门店管理接口获取门店位置ID
   */
  @JsonProperty("location_id_list")
  private String[] locationIds;

  /** 设置本卡券支持全部门店，与location_id_list互斥 */
  @JsonProperty("use_all_locations")
  private Boolean useAllLocations;

  /**
   * 第三方来源名，例如同程旅游、大众点评
   */
  private String source;

  /**
   * 自定义跳转外链的入口名字
   */
  @JsonProperty("custom_url_name")
  private String customUrlName;

  /**
   * 自定义跳转的URL
   */
  @JsonProperty("custom_url")
  private String customUrl;

  /**
   * 显示在入口右侧的提示语
   */
  @JsonProperty("custom_url_sub_title")
  private String customUrlSubTitle;

  /** 顶部居中按钮 */
  @JsonProperty("center_title")
  private String centerTitle;

  /** 按钮下方的wording */
  @JsonProperty("center_sub_title")
  private String centerSubTitle;

  /** 按钮链接 */
  @JsonProperty("center_url")
  private String centerUrl;

  /**
   * 营销场景的自定义入口名称
   */
  @JsonProperty("promotion_url_name")
  private String promotionUrlName;

  /**
   * 入口跳转外链的地址链接
   */
  @JsonProperty("promotion_url")
  private String promotionUrl;

  /**
   * 显示在营销入口右侧的提示语
   */
  @JsonProperty("promotion_url_sub_title")
  private String promotionUrlSubTitle;

  /**
   * 每人可领券的数量限制
   */
  @JsonProperty("get_limit")
  private Integer getLimit;

  /** 每人可核销的数量限制,不填写默认为50。 */
  @JsonProperty("use_limit")
  private Integer useLimit;

  /**
   * 卡券领取页面是否可分享
   */
  @JsonProperty("can_share")
  private Boolean canShare;

  /**
   * 卡券是否可转赠
   */
  @JsonProperty("can_give_friend")
  private Boolean canGiveFriend;

  /** 填写true为用户点击进入会员卡时推送事件，默认为false */
  @JsonProperty("need_push_on_view")
  private Boolean needPushOnView;

  /** 支付功能结构体 */
  @JsonProperty("pay_info")
  private PayInfo payInfo;

  /** 创建时间 */
  @JsonProperty("create_time")
  @JsonDeserialize(using = DateDeserializer.class)
  private Date createTime;

  /** 更新时间 */
  @JsonProperty("update_time")
  @JsonDeserialize(using = DateDeserializer.class)
  private Date updateTime;

  /** 自定义使用入口跳转小程序的user_name，格式为原始id+@app */
  @JsonProperty("custom_app_brand_user_name")
  private String customAppBrandUserName;

  /** 自定义使用入口小程序页面地址 */
  @JsonProperty("custom_app_brand_pass")
  private String customAppBrandPass;

  /** 小程序的user_name */
  @JsonProperty("center_app_brand_user_name")
  private String centerAppBrandUserName;

  /** 自定义居中使用入口小程序页面地址 */
  @JsonProperty("center_app_brand_pass")
  private String centerAppBrandPass;

  /** 小程序的user_name */
  @JsonProperty("promotion_app_brand_user_name")
  private String promotionAppBrandUserName;

  /** 自定义营销入口小程序页面地址 */
  @JsonProperty("promotion_app_brand_pass")
  private String promotionAppBrandPass;

  /** 小程序的user_name */
  @JsonProperty("activate_app_brand_user_name")
  private String activateAppBrandUserName;

  /** 激活小程序页面地址 */
  @JsonProperty("activate_app_brand_pass")
  private String activateAppBrandPass;

  public Date getCreateTime() {
    return createTime;
  }

  public void setCreateTime(Date createTime) {
    this.createTime = createTime;
  }

  public Date getUpdateTime() {
    return updateTime;
  }

  public void setUpdateTime(Date updateTime) {
    this.updateTime = updateTime;
  }

  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public CardStatus getStatus() {
    return status;
  }

  public void setStatus(CardStatus status) {
    this.status = status;
  }

  public String getLogoUrl() {
    return logoUrl;
  }

  public void setLogoUrl(String logoUrl) {
    this.logoUrl = logoUrl;
  }

  public CodeType getCodeType() {
    return codeType;
  }

  public void setCodeType(CodeType codeType) {
    this.codeType = codeType;
  }

  public String getBrandName() {
    return brandName;
  }

  public void setBrandName(String brandName) {
    this.brandName = brandName;
  }

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public String getColor() {
    return color;
  }

  public void setColor(String color) {
    this.color = color;
  }

  public String getNotice() {
    return notice;
  }

  public void setNotice(String notice) {
    this.notice = notice;
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  public Sku getSku() {
    return sku;
  }

  public void setSku(Sku sku) {
    this.sku = sku;
  }

  public DateInfo getDateInfo() {
    return dateInfo;
  }

  public void setDateInfo(DateInfo dateInfo) {
    this.dateInfo = dateInfo;
  }

  public Boolean getUseCustomCode() {
    return useCustomCode;
  }

  public void setUseCustomCode(Boolean useCustomCode) {
    this.useCustomCode = useCustomCode;
  }

  public GetCustomCodeMode getGetCustomCodeMode() {
    return getCustomCodeMode;
  }

  public void setGetCustomCodeMode(GetCustomCodeMode getCustomCodeMode) {
    this.getCustomCodeMode = getCustomCodeMode;
  }

  public Boolean getBindOpenId() {
    return bindOpenId;
  }

  public void setBindOpenId(Boolean bindOpenId) {
    this.bindOpenId = bindOpenId;
  }

  public String getServicePhone() {
    return servicePhone;
  }

  public void setServicePhone(String servicePhone) {
    this.servicePhone = servicePhone;
  }

  public String[] getLocationIds() {
    return locationIds;
  }

  public void setLocationIds(String[] locationIds) {
    this.locationIds = locationIds;
  }

  public Boolean getUseAllLocations() {
    return useAllLocations;
  }

  public void setUseAllLocations(Boolean useAllLocations) {
    this.useAllLocations = useAllLocations;
  }

  public String getSource() {
    return source;
  }

  public void setSource(String source) {
    this.source = source;
  }

  public String getCustomUrlName() {
    return customUrlName;
  }

  public void setCustomUrlName(String customUrlName) {
    this.customUrlName = customUrlName;
  }

  public String getCustomUrl() {
    return customUrl;
  }

  public void setCustomUrl(String customUrl) {
    this.customUrl = customUrl;
  }

  public String getCustomUrlSubTitle() {
    return customUrlSubTitle;
  }

  public void setCustomUrlSubTitle(String customUrlSubTitle) {
    this.customUrlSubTitle = customUrlSubTitle;
  }

  public String getCenterTitle() {
    return centerTitle;
  }

  public void setCenterTitle(String centerTitle) {
    this.centerTitle = centerTitle;
  }

  public String getCenterSubTitle() {
    return centerSubTitle;
  }

  public void setCenterSubTitle(String centerSubTitle) {
    this.centerSubTitle = centerSubTitle;
  }

  public String getCenterUrl() {
    return centerUrl;
  }

  public void setCenterUrl(String centerUrl) {
    this.centerUrl = centerUrl;
  }

  public String getPromotionUrlName() {
    return promotionUrlName;
  }

  public void setPromotionUrlName(String promotionUrlName) {
    this.promotionUrlName = promotionUrlName;
  }

  public String getPromotionUrl() {
    return promotionUrl;
  }

  public void setPromotionUrl(String promotionUrl) {
    this.promotionUrl = promotionUrl;
  }

  public String getPromotionUrlSubTitle() {
    return promotionUrlSubTitle;
  }

  public void setPromotionUrlSubTitle(String promotionUrlSubTitle) {
    this.promotionUrlSubTitle = promotionUrlSubTitle;
  }

  public Integer getGetLimit() {
    return getLimit;
  }

  public void setGetLimit(Integer getLimit) {
    this.getLimit = getLimit;
  }

  public Integer getUseLimit() {
    return useLimit;
  }

  public void setUseLimit(Integer useLimit) {
    this.useLimit = useLimit;
  }

  public Boolean getCanShare() {
    return canShare;
  }

  public void setCanShare(Boolean canShare) {
    this.canShare = canShare;
  }

  public Boolean getCanGiveFriend() {
    return canGiveFriend;
  }

  public void setCanGiveFriend(Boolean canGiveFriend) {
    this.canGiveFriend = canGiveFriend;
  }

  public Boolean getNeedPushOnView() {
    return needPushOnView;
  }

  public void setNeedPushOnView(Boolean needPushOnView) {
    this.needPushOnView = needPushOnView;
  }

  public PayInfo getPayInfo() {
    return payInfo;
  }

  public void setPayInfo(PayInfo payInfo) {
    this.payInfo = payInfo;
  }

  public String getCustomAppBrandUserName() {
    return customAppBrandUserName;
  }

  public void setCustomAppBrandUserName(String customAppBrandUserName) {
    this.customAppBrandUserName = customAppBrandUserName;
  }

  public String getCustomAppBrandPass() {
    return customAppBrandPass;
  }

  public void setCustomAppBrandPass(String customAppBrandPass) {
    this.customAppBrandPass = customAppBrandPass;
  }

  public String getCenterAppBrandUserName() {
    return centerAppBrandUserName;
  }

  public void setCenterAppBrandUserName(String centerAppBrandUserName) {
    this.centerAppBrandUserName = centerAppBrandUserName;
  }

  public String getCenterAppBrandPass() {
    return centerAppBrandPass;
  }

  public void setCenterAppBrandPass(String centerAppBrandPass) {
    this.centerAppBrandPass = centerAppBrandPass;
  }

  public String getPromotionAppBrandUserName() {
    return promotionAppBrandUserName;
  }

  public void setPromotionAppBrandUserName(String promotionAppBrandUserName) {
    this.promotionAppBrandUserName = promotionAppBrandUserName;
  }

  public String getPromotionAppBrandPass() {
    return promotionAppBrandPass;
  }

  public void setPromotionAppBrandPass(String promotionAppBrandPass) {
    this.promotionAppBrandPass = promotionAppBrandPass;
  }

  public String getActivateAppBrandUserName() {
    return activateAppBrandUserName;
  }

  public void setActivateAppBrandUserName(String activateAppBrandUserName) {
    this.activateAppBrandUserName = activateAppBrandUserName;
  }

  public String getActivateAppBrandPass() {
    return activateAppBrandPass;
  }

  public void setActivateAppBrandPass(String activateAppBrandPass) {
    this.activateAppBrandPass = activateAppBrandPass;
  }

  public static class DateInfo implements Serializable {
    private static final long serialVersionUID = 6952242333681766650L;

    /**
     * 使用时间的类型，仅支持填写1或2。1为固定日期区间，2为固定时长（自领取后按天算）。
     */
    @JsonProperty("type")
    private DateInfoType type;

    /**
     * type为1时专用，表示起用时间。 从1970年1月1日00:00:00至起用时间的秒数，最终需转换为字符串形态传入。（东八区时间，单位为秒）
     */
    @JsonProperty("begin_timestamp")
    @JsonSerialize(using = DateSerializer.class)
    private Date beginTime;

    /**
     * type为1时专用，表示结束时间。 建议设置为截止日期的23:59:59过期。（东八区时间，单位为秒）
     */
    @JsonProperty("end_timestamp")
    @JsonSerialize(using = DateSerializer.class)
    private Date endTime;

    /**
     * type为2时专用，表示自领取后多少天内有效，领取后当天有效填写0。（单位为天）
     */
    @JsonProperty("fixed_term")
    private Integer fixedTerm;

    /**
     * type为2时专用，表示自领取后多少天开始生效。（单位为天）
     */
    @JsonProperty("fixed_begin_term")
    private Integer fixedTermBegin;

    public DateInfoType getType() {
      return type;
    }

    public void setType(DateInfoType type) {
      this.type = type;
    }

    public Date getBeginTime() {
      return beginTime;
    }

    public void setBeginTime(Date beginTime) {
      this.beginTime = beginTime;
    }

    public Date getEndTime() {
      return endTime;
    }

    public void setEndTime(Date endTime) {
      this.endTime = endTime;
    }

    public Integer getFixedTerm() {
      return fixedTerm;
    }

    public void setFixedTerm(Integer fixedTerm) {
      this.fixedTerm = fixedTerm;
    }

    public Integer getFixedTermBegin() {
      return fixedTermBegin;
    }

    public void setFixedTermBegin(Integer fixedTermBegin) {
      this.fixedTermBegin = fixedTermBegin;
    }

    public enum DateInfoType {

      DATE_TYPE_FIX_TIME_RANGE(1), DATE_TYPE_FIX_TERM(2);

      private int code;

      DateInfoType(int code) {
        this.code = code;
      }

      public static DateInfoType fromCode(int code) {
        for (DateInfoType dateInfoType : DateInfoType.values()) {
          if (dateInfoType.code == code) {
            return dateInfoType;
          }
        }
        return DateInfoType.DATE_TYPE_FIX_TERM;
      }

      public int getCode() {
        return this.code;
      }
    }
  }

  /**
   * 商品信息
   */
  public static class Sku implements Serializable {
    private static final long serialVersionUID = -8672077742144314082L;

    /**
     * 卡券库存的数量，上限为100000000。, 预存code模式的卡券须设置quantity为0，导入code后方可增加库存
     */
    private Integer quantity;

    public Sku() {
    }

    public Sku(Integer quantity) {
      this.quantity = quantity;
    }

    public Integer getQuantity() {
      return quantity;
    }

    public void setQuantity(Integer quantity) {
      this.quantity = quantity;
    }

  }

  /**
   * @author Debenson
   * @since 0.1
   */
  public static enum GetCustomCodeMode {
    GET_CUSTOM_CODE_MODE_DEPOSIT
  }

  /**
   * 卡券状态。
   * 
   * @author Debenson
   * @since 0.1
   */
  public static enum CardStatus {
    CARD_STATUS_NOT_VERIFY, // 待审核；
    CARD_STATUS_VERIFY_FAIL, // 审核失败；
    CARD_STATUS_VERIFY_OK, // 通过审核；
    CARD_STATUS_DELETE, // 卡券被商户删除；
    CARD_STATUS_DISPATCH, // 在公众平台投放过的卡券；
  }

  /**
   * Code展示类型
   * 
   * @author Debenson
   * @since 0.1
   */
  public static enum CodeType {
    CODE_TYPE_TEXT, // 文本

    CODE_TYPE_BARCODE, // 一维码

    CODE_TYPE_QRCODE, // 二维码

    CODE_TYPE_ONLY_QRCODE, // 仅显示二维码

    CODE_TYPE_ONLY_BARCODE, // 仅显示一维码

    CODE_TYPE_NONE, // 不显示任何码型

  }

  /**
   * 支付功能结构体
   * 
   * @author Debenson
   * @since 0.1
   */
  public static class PayInfo implements Serializable {
    private static final long serialVersionUID = -4997571120409030071L;

    @JsonProperty("swipe_card")
    private SwipeCard swipeCard;

    public SwipeCard getSwipeCard() {
      return swipeCard;
    }

    public void setSwipeCard(SwipeCard swipeCard) {
      this.swipeCard = swipeCard;
    }

  }

  /**
   * 刷卡功能结构体
   * 
   * @author Debenson
   * @since 0.1
   */
  public static class SwipeCard implements Serializable {
    private static final long serialVersionUID = -4997571120409030071L;

    @JsonProperty("is_swipe_card")
    private Boolean isSwipeCard;
    @JsonProperty("is_pay_and_qrcode")
    private Boolean isPayAndQrcode;

    public SwipeCard() {
    }

    public SwipeCard(boolean isSwipeCard, boolean isPayAndQrcode) {
      this.isSwipeCard = isSwipeCard;
      this.isPayAndQrcode = isPayAndQrcode;
    }

    /** 是否设置该会员卡支持拉出微信支付刷卡界面 */
    public Boolean getIsSwipeCard() {
      return isSwipeCard;
    }

    public void setIsSwipeCard(Boolean isSwipeCard) {
      this.isSwipeCard = isSwipeCard;
    }

    /** 是否设置该会员卡中部的按钮同时支持微信支付刷卡和会员卡二维码 */
    public Boolean getIsPayAndQrcode() {
      return isPayAndQrcode;
    }

    public void setIsPayAndQrcode(Boolean isPayAndQrcode) {
      this.isPayAndQrcode = isPayAndQrcode;
    }
  }

}
